package com.leonzx.base.controller.base;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.beans.PropertyEditorSupport;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/** 
 * @ClassName: MyCustomDateEditor 
 * @Description: 自定义Date类型参数处理器 
 * @author L-liang
 * @date 2015年10月9日 下午3:56:19 
 *  
 */
public class CustomDateEditor extends PropertyEditorSupport{
	private static final Logger logger = LoggerFactory.getLogger(CustomDateEditor.class);

	private final DateFormat dateFormat;

	private final boolean allowEmpty;

	private final int exactDateLength;


	/**
	 * Create a new CustomDateEditor instance, using the given DateFormat
	 * for parsing and rendering.
	 * <p>The "allowEmpty" parameter states if an empty String should
	 * be allowed for parsing, i.e. get interpreted as null value.
	 * Otherwise, an IllegalArgumentException gets thrown in that case.
	 * @param dateFormat DateFormat to use for parsing and rendering
	 * @param allowEmpty if empty strings should be allowed
	 */
	public CustomDateEditor(DateFormat dateFormat, boolean allowEmpty) {
		this.dateFormat = dateFormat;
		this.allowEmpty = allowEmpty;
		this.exactDateLength = -1;
	}

	/**
	 * Create a new CustomDateEditor instance, using the given DateFormat
	 * for parsing and rendering.
	 * <p>The "allowEmpty" parameter states if an empty String should
	 * be allowed for parsing, i.e. get interpreted as null value.
	 * Otherwise, an IllegalArgumentException gets thrown in that case.
	 * <p>The "exactDateLength" parameter states that IllegalArgumentException gets
	 * thrown if the String does not exactly match the length specified. This is useful
	 * because SimpleDateFormat does not enforce strict parsing of the year part,
	 * not even with {@code setLenient(false)}. Without an "exactDateLength"
	 * specified, the "01/01/05" would get parsed to "01/01/0005". However, even
	 * with an "exactDateLength" specified, prepended zeros in the day or month
	 * part may still allow for a shorter year part, so consider this as just
	 * one more assertion that gets you closer to the intended date format.
	 * @param dateFormat DateFormat to use for parsing and rendering
	 * @param allowEmpty if empty strings should be allowed
	 * @param exactDateLength the exact expected length of the date String
	 */
	public CustomDateEditor(DateFormat dateFormat, boolean allowEmpty, int exactDateLength) {
		this.dateFormat = dateFormat;
		this.allowEmpty = allowEmpty;
		this.exactDateLength = exactDateLength;
	}


	/**
	 * Parse the Date from the given text, using the specified DateFormat.
	 */
	@Override
	public void setAsText(String text) throws IllegalArgumentException{
		if (this.allowEmpty && !StringUtils.hasText(text)) {
			// Treat empty String as null value.
			setValue(null);
		}
		else if (text != null && this.exactDateLength >= 0 && text.length() != this.exactDateLength) {
			throw new IllegalArgumentException(
					"Could not parse date: it is not exactly" + this.exactDateLength + "characters long");
		}
		else {
			Object obj  = null;
			//正则解析时间字符串
			String reg = "(\\d{2,4})(-(\\d{1,2})(-(\\d{1,2})( (\\d{1,2})(:(\\d{1,2})(:(\\d{1,2}))*)*)*)*)*";
			Pattern pattern = Pattern.compile(reg);
			Matcher matcher = pattern.matcher(text);
			if(matcher.find()){
				String group1 = matcher.group(1);
				String group2 = matcher.group(2);
				String group4 = matcher.group(4);
				String group6 = matcher.group(6);
				String group8 = matcher.group(8);
				String group10 = matcher.group(10);
				if(StringUtils.isEmpty(group1)){
					//obj = null
				}else{
					if(StringUtils.isEmpty(group2)){
						if(text.endsWith("-")){
							text += "01-01 00:00:00";
						}else{
							text += "-01-01 00:00:00";
						}
					}else if(StringUtils.isEmpty(group4)){
						if(text.endsWith("-")){
							text += "01 00:00:00";
						}else{
							text += "-01 00:00:00";
						}
					}else if(StringUtils.isEmpty(group6)){
						if(text.endsWith(" ")){
							text += "00:00:00";
						}else{
							text += " 00:00:00";
						}
					}else if(StringUtils.isEmpty(group8)){
						if(text.endsWith(":")){
							text += "00:00";
						}else{
							text += ":00:00";
						}
					}else if(StringUtils.isEmpty(group10)){
						if(text.endsWith(":")){
							text += "00";
						}else{
							text += ":00";
						}
					}
					
					try {
						obj = this.dateFormat.parse(text);
					} catch (ParseException e) {
						logger.error("正则解析时间字符串text=="+text,e);
					}
				}
			}
			setValue(obj);
		}
	}

	/**
	 * Format the Date as String, using the specified DateFormat.
	 */
	@Override
	public String getAsText() {
		Date value = (Date) getValue();
		return (value != null ? this.dateFormat.format(value) : "");
	}
}
